package com.ruoyi.web.controller.teacher;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.domain.*;
import com.ruoyi.dto.BasisLoadingUavCamp;
import com.ruoyi.service.WordService;
import io.swagger.models.auth.In;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;

@RestController
@RequestMapping("/word")
public class Word {

    @Autowired
    WordService wordService;

    // 字体常量
    private static final String FONT_FAMILY = "SimSun"; // 宋体
    private static final int FONT_SIZE = 18; // 五号字体对应的磅值(10.5磅，POI中取整)
    private static final int FIRST_LINE_INDENT = 420; // 首行缩进两个字符的磅值(一个中文字符约210磅)


    @GetMapping("/downloadWord")
    public ResponseEntity<byte[]> downloadWord(String loadingId) throws IOException {
        Map<String, Object> position = wordService.findPosition(loadingId);

        XWPFDocument document = generateWord(position, "评估报告_测试案例0628.doc");

        try {


            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            document.write(bos); // 关键行：确认此处是否抛出异常
            byte[] docBytes = bos.toByteArray();
            bos.close();

            // 设置响应头...
            return ResponseEntity.ok().body(docBytes);
        } finally {
            if (document != null) {
                document.close();
            }
        }

    }




    /**
     * 生成Word文档
     */
    public static XWPFDocument  generateWord(Map<String, Object> jsonMap, String outputPath) throws IOException {
        XWPFDocument document = new XWPFDocument();
        try  {
            // 获取案例名称
            BasisCaseLoading loadingParam = (BasisCaseLoading) jsonMap.get("loadingParam");
            String caseName = loadingParam.getCaseName();

            // 添加文档标题
            addTitle(document, caseName);

            // 添加目录
            generateTableOfContents(document);

            // 1. 总体任务
            addSection(document, "1 总体任务", 1, loadingParam.getOveralltask());

            // 2. 演训案例时间
            addSection(document, "2 演训案例时间", 1, loadingParam.getCasePeriodOfTime());

//            // 3. 案例场景信息
//            String sceneInfo = buildSceneInformation(jsonMap);
//            addSection(document, "3 案例场景信息", 1, sceneInfo);
//
//            // 4. 案例任务信息
//            addSection(document, "3 案例任务信息", 1, "本次演训案例包含 " + getTaskCount(jsonMap) + " 个任务");
//            buildTaskInformation(document, jsonMap);

            // 5. 演训成绩
//            String scoresInfo = buildTrainingScores(jsonMap);
            Integer sumPos = Integer.parseInt(jsonMap.get("posionSum").toString());
            String person = jsonMap.get("person").toString();
            addSection(document, "3 演训成绩", 1, "本次演训共有"+sumPos+"个阵地，共有"+person+"人参与，以下是详细成绩：");
            List<ScoreAndPos> list = (List<ScoreAndPos>) jsonMap.get("scoreAndPos");

            addTrainingScoreTable(document, buildTrainingScoreData(list));



            String content = jsonMap.get("summaryContent").toString();
            addSection(document, "4 演训总结", 1, content);



            // 保存文档
            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                document.write(fos);
            }
            System.out.println("Word文档生成成功：" + outputPath);
            return document;
        }catch (Exception e){
            e.printStackTrace();
            document.close();
        }
        return document;
    }

    /**
     * 添加文档标题
     */
    private static void addTitle(XWPFDocument document, String title) {
        XWPFParagraph titlePara = document.createParagraph();
        titlePara.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleRun = titlePara.createRun();
        titleRun.setText(title);
        titleRun.setBold(true);
        titleRun.setFontFamily(FONT_FAMILY);
        titleRun.setFontSize(FONT_SIZE);
    }

//    /**
//     * 生成目录
//     */
//    private static void generateTableOfContents(XWPFDocument document) {
//        XWPFParagraph tocTitle = document.createParagraph();
//        tocTitle.setAlignment(ParagraphAlignment.CENTER);
//        XWPFRun tocTitleRun = tocTitle.createRun();
//        tocTitleRun.setText("培训报告");
//        tocTitleRun.setBold(true);
//        tocTitleRun.setFontSize(FONT_SIZE);
//        tocTitleRun.setFontFamily(FONT_FAMILY);
//
//       // document.createParagraph(); // 空行
//
//        // 添加目录字段
//        XWPFParagraph tocParagraph = document.createParagraph();
//        CTP ctp = tocParagraph.getCTP();
//        CTPPr ppr = ctp.addNewPPr();
//        ppr.addNewSpacing().setAfter(BigInteger.valueOf(360));
//
//        // 目录字段开始
//        CTFldChar fldChar = ctp.addNewR().addNewFldChar();
//        fldChar.setFldCharType(STFldCharType.BEGIN);
//
//        // 目录指令
//        CTR run = ctp.addNewR();
//        run.addNewInstrText().setStringValue("TOC \\o \"1-9\" \\h \\z \\u \\f \"Heading\"");
//
//        // 目录字段结束
//        fldChar = ctp.addNewR().addNewFldChar();
//        fldChar.setFldCharType(STFldCharType.END);
//
//       // document.createParagraph(); // 空行
//    }
private static void generateTableOfContents(XWPFDocument document) {
    // 创建目录标题段落
    XWPFParagraph tocTitle = document.createParagraph();
    tocTitle.setAlignment(ParagraphAlignment.CENTER);
    XWPFRun tocTitleRun = tocTitle.createRun();
    tocTitleRun.setText("培训报告");
    tocTitleRun.setBold(true);
    tocTitleRun.setFontSize(FONT_SIZE);
    tocTitleRun.setFontFamily(FONT_FAMILY);

    // 添加目录字段
    XWPFParagraph tocParagraph = document.createParagraph();
    CTP ctp = tocParagraph.getCTP();
    CTPPr ppr = ctp.addNewPPr();
    ppr.addNewSpacing().setAfter(BigInteger.valueOf(360));

    // 目录字段开始
    CTFldChar fldChar = ctp.addNewR().addNewFldChar();
    fldChar.setFldCharType(STFldCharType.BEGIN);

    // 目录指令
    CTR run = ctp.addNewR();
    run.addNewInstrText().setStringValue("TOC \\o \"1-9\" \\h \\z \\u \\f \"Heading\"");

    // 目录字段结束
    fldChar = ctp.addNewR().addNewFldChar();
    fldChar.setFldCharType(STFldCharType.END);
}
    /**
     * 添加章节
     */
    private static void addSection(XWPFDocument document, String title, int level, String content) {
        // 添加标题
        XWPFParagraph headingPara = document.createParagraph();
        setHeadingStyle(headingPara, title, level);

        // 添加内容
        if (content != null && !content.isEmpty()) {
            XWPFParagraph contentPara = document.createParagraph();
            XWPFRun contentRun = contentPara.createRun();
            contentRun.setText(content);
            contentRun.setFontFamily(FONT_FAMILY);
            contentRun.setFontSize(FONT_SIZE);
            // 设置首行缩进
            CTPPr paraPr = contentPara.getCTP().isSetPPr() ?
                    contentPara.getCTP().getPPr() :
                    contentPara.getCTP().addNewPPr();
            paraPr.addNewInd().setFirstLine(BigInteger.valueOf(FIRST_LINE_INDENT));

            contentPara.setStyle("Normal");
        }

     //   document.createParagraph(); // 空行
    }

    /**
     * 设置标题样式
     */
    private static void setHeadingStyle(XWPFParagraph para, String title, int level) {
        CTPPr ppr = para.getCTP().isSetPPr() ?
                para.getCTP().getPPr() :
                para.getCTP().addNewPPr();

        // 设置大纲级别
        ppr.setOutlineLvl(CTDecimalNumber.Factory.newInstance());
        ppr.getOutlineLvl().setVal(BigInteger.valueOf(level - 1));

        // 设置段落间距
        ppr.addNewSpacing().setBefore(BigInteger.valueOf(180));
        ppr.addNewSpacing().setAfter(BigInteger.valueOf(180));

        // 应用标题样式
        para.setStyle("Heading" + level);

        // 设置标题内容
        XWPFRun run = para.createRun();
        run.setText(title);
        run.setBold(true);
        run.setFontFamily(FONT_FAMILY);
        run.setFontSize(12 + (4 - level) * 2); // 标题级别越高字体越小
    }

    /**
     * 构建案例场景信息
     */
    @SuppressWarnings("unchecked")
    private static String buildSceneInformation(Map<String, Object> jsonMap) {
        // 红方阵地
        List<BasisPosition> positionParam = (List<BasisPosition>) jsonMap.get("BasisPositionParam");
        String redPositions = "红方阵地：";
        if (positionParam != null && !positionParam.isEmpty()) {
            for (BasisPosition pos : positionParam) {
                redPositions += pos.getPositionName() + "、";
            }
            redPositions = redPositions.substring(0, redPositions.length() - 1);
        }

        // 红方设备
        ArrayList<BasisEquipmentInformationv> equipmentParam = (ArrayList<BasisEquipmentInformationv>) jsonMap.get("BasisEquipmentInformationvParam");
        String redEquipment = "红方设备：";
        if (equipmentParam != null && !equipmentParam.isEmpty()) {
            for (BasisEquipmentInformationv eq : equipmentParam) {
                redEquipment += eq.getEquipmentName()+ "、";
            }
            redEquipment = redEquipment.substring(0, redEquipment.length() - 1);
        }

        // 学员
        List<UserData> userDataParam = (List<UserData>) jsonMap.get("UserDataParam");
        String trainees = "学员：";
        if (userDataParam != null && !userDataParam.isEmpty()) {
            for (UserData user : userDataParam) {
                trainees += user.getNickName() + "、";
            }
            trainees = trainees.substring(0, trainees.length() - 1);
        }

        // 无人机（蓝方目标）
        List<BasisLoadingUavCamp> uavParam = (List<BasisLoadingUavCamp>) jsonMap.get("uavParam");
        String uavInfo = "蓝方目标：";
        if (uavParam != null && !uavParam.isEmpty()) {
            for (BasisLoadingUavCamp uav : uavParam) {
                uavInfo += uav.getName() + "、";
            }
            uavInfo = uavInfo.substring(0, uavInfo.length() - 1);
        }

        return "本次演训案例红方包含" + positionParam.size() + "个阵地，" +
                redPositions + "；" + equipmentParam.size() + "个设备，" + redEquipment + "；" +
                userDataParam.size() + "个学员，" + trainees + "。" +
                "蓝方包含" + uavParam.size() + "个目标，" + uavInfo + "。";
    }

    /**
     * 构建任务信息
     */
    @SuppressWarnings("unchecked")
    private static void buildTaskInformation(XWPFDocument document, Map<String, Object> jsonMap) {
        List<BasisCaseLoadingTask> taskParam = (List<BasisCaseLoadingTask>) jsonMap.get("taskParam");
        if (taskParam != null && !taskParam.isEmpty()) {
            for (int i = 0; i < taskParam.size(); i++) {
                BasisCaseLoadingTask task = taskParam.get(i);
                String taskName = task.getTaskName();
                String taskNumber = "4." + (i + 1);

                // 任务标题（二级标题）
                addSection(document, taskNumber + " " + taskName, 2, "");

                // 1) 任务目标（三级标题）
                String taskObjective = (String) task.getTaskObjective();
                addSection(document, "1) 任务目标", 3, taskObjective);

                // 2) 任务内容（三级标题）
                addSection(document, "2) 任务内容", 3, taskName );

                // 3) 我方阵地规划（三级标题）
                String positionPlanning = buildPositionPlanning(jsonMap);
                addSection(document, "3) 我方阵地规划", 3, positionPlanning);

                // 4) 我方力量分配（三级标题）
                String forceAllocation = buildForceAllocation(jsonMap);
                addSection(document, "4) 我方力量分配", 3, forceAllocation);

                // 5) 参训人员分配（三级标题）
                String userName = (String) task.getUserName();
                addSection(document, "5) 参训人员分配", 3, "参训人员：" + (userName != null ? userName : "无"));
            }
        }
    }

    /**
     * 构建阵地规划内容
     */
    @SuppressWarnings("unchecked")
    private static String buildPositionPlanning(Map<String, Object> jsonMap) {
        List<BasisPosition> positionParam  = (List<BasisPosition>) jsonMap.get("BasisPositionParam");
        StringBuilder sb = new StringBuilder();
        if (positionParam != null && !positionParam.isEmpty()) {
            for (BasisPosition pos : positionParam) {
                sb.append(pos.getPositionName()+" - 经纬度：");
                sb.append(pos.getLongitude()+", "+pos.getLatitude()+"\n");
            }
        }
        return sb.toString();
    }

    /**
     * 构建力量分配内容
     */
    @SuppressWarnings("unchecked")
    private static String buildForceAllocation(Map<String, Object> jsonMap) {
        ArrayList<BasisEquipmentInformationv> equipmentParam = (ArrayList<BasisEquipmentInformationv>) jsonMap.get("BasisEquipmentInformationvParam");
        StringBuilder sb = new StringBuilder("力量分配：\n");
        if (equipmentParam != null && !equipmentParam.isEmpty()) {
            for (BasisEquipmentInformationv eq : equipmentParam) {
                sb.append("- ").append(eq.getEquipmentName()).append("\n");
            }
        }
        return sb.toString();
    }

    /**
     * 构建演训成绩内容
     */
    @SuppressWarnings("unchecked")
    private static String buildTrainingScores(Map<String, Object> jsonMap) {
        List<UserData> userDataParam = (List<UserData>) jsonMap.get("UserDataParam");
        if (userDataParam == null || userDataParam.isEmpty()) {
            return "无演训成绩数据";
        }

        StringBuilder sb = new StringBuilder("本次参加演训的学员共").append(userDataParam.size()).append("人，成绩如下：\n\n");
        sb.append("| 学员名称 | 成绩 |\n");
        sb.append("|---------|------|\n");

        Random random = new Random();
        for (UserData user : userDataParam) {
            String name = (String) user.getNickName();
            int score = 80 + random.nextInt(21); // 80-100分
            sb.append("| ").append(name).append(" | ").append(score).append(" |\n");
        }
        return sb.toString();
    }

    /**
     * 获取任务数量
     */
    @SuppressWarnings("unchecked")
    private static int getTaskCount(Map<String, Object> jsonMap) {
        List<BasisCaseLoadingTask> taskParam = (List<BasisCaseLoadingTask>) jsonMap.get("taskParam");
        return taskParam != null ? taskParam.size() : 0;
    }


//    public static void addTrainingScoreTable(XWPFDocument document, List<Map<String, Object>> scoreData) {
//        // 表格标题
////        XWPFParagraph titlePara = document.createParagraph();
////        titlePara.setAlignment(ParagraphAlignment.CENTER);
////        XWPFRun titleRun = titlePara.createRun();
////        titleRun.setText("演训成绩表");
////        titleRun.setBold(true);
////        titleRun.setFontSize(14);
//
//        // 创建表格（表头 + 数据行）
//        XWPFTable table = document.createTable(scoreData.size() + 1, 2);
//
//        // 设置表头
//        String[] headers = {"阵地名称", "成绩"};
//        XWPFTableRow headerRow = table.getRow(0);
//        for (int i = 0; i < headers.length; i++) {
//            headerRow.getCell(i).setText(headers[i]);
//
//            // 表头样式
//            XWPFParagraph cellPara = headerRow.getCell(i).getParagraphs().get(0);
//            XWPFRun cellRun = cellPara.createRun();
//            cellRun.setFontSize(40);
//            cellRun.setBold(true);
//        }
//
//        // 填充数据
//        for (int i = 0; i < scoreData.size(); i++) {
//            XWPFTableRow dataRow = table.getRow(i + 1);
//            Map<String, Object> row = scoreData.get(i);
//            dataRow.getCell(0).setText(row.get("poName").toString());
//            dataRow.getCell(1).setText(row.get("sumScore").toString());
//        }
//    }

    public static void addTrainingScoreTable(XWPFDocument document, List<Map<String, Object>> scoreData) {
        // 创建表格（表头 + 数据行）
        XWPFTable table = document.createTable(scoreData.size() + 1, 2);

        // 设置表格整体样式
        table.setWidth("100%"); // 表格宽度占满页面
        //table.setTableAlignment(TableAlignment.CENTER); // 表格在页面居中

        // 设置表头
        String[] headers = {"阵地名称", "成绩"};
        XWPFTableRow headerRow = table.getRow(0);
        headerRow.setHeight(500); // 设置表头行高

        for (int i = 0; i < headers.length; i++) {
            XWPFTableCell headerCell = headerRow.getCell(i);
            headerCell.setText(headers[i]);

            // 设置表头单元格样式
            XWPFParagraph cellPara = headerCell.getParagraphs().get(0);
            cellPara.setAlignment(ParagraphAlignment.CENTER); // 文字水平居中

            XWPFRun cellRun = cellPara.getRuns().isEmpty()
                    ? cellPara.createRun()
                    : cellPara.getRuns().get(0);
            cellRun.setFontSize(12); // 设置字体大小
            cellRun.setBold(true); // 设置加粗
            cellRun.setFontFamily("宋体"); // 设置字体

            // 设置单元格垂直居中
            headerCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        }

        // 填充数据
        for (int i = 0; i < scoreData.size(); i++) {
            XWPFTableRow dataRow = table.getRow(i + 1);
            dataRow.setHeight(400); // 设置数据行高

            Map<String, Object> row = scoreData.get(i);

            // 设置数据单元格样式
            for (int j = 0; j < 2; j++) {
                XWPFTableCell dataCell = dataRow.getCell(j);
                String text = j == 0 ? row.get("poName").toString() : row.get("sumScore").toString();
                dataCell.setText(text);

                XWPFParagraph cellPara = dataCell.getParagraphs().get(0);
                cellPara.setAlignment(ParagraphAlignment.CENTER); // 文字水平居中

                XWPFRun cellRun = cellPara.getRuns().isEmpty()
                        ? cellPara.createRun()
                        : cellPara.getRuns().get(0);
                cellRun.setFontSize(12); // 设置字体大小
                cellRun.setFontFamily("宋体"); // 设置字体

                // 设置单元格垂直居中
                dataCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            }
        }

        // 在表格后添加空行，使文档更美观
     //   document.createParagraph();
    }
    /**
     * 构建演训成绩数据
     */
    private static List<Map<String, Object>> buildTrainingScoreData(List<ScoreAndPos> list) {
        List<Map<String, Object>> scoreData = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)){

            for (ScoreAndPos scoreAndPos:list){
                Map<String, Object> score1 = new HashMap<>();
                score1.put("poName",scoreAndPos.getPosName());
                score1.put("sumScore",scoreAndPos.getSumScore());
                scoreData.add(score1);
            }
        }
        return scoreData;
    }
}
